package com.example.wifiunlockscreen.support;

import java.util.List;

import android.app.KeyguardManager.KeyguardLock;
import android.app.Activity;
import android.app.KeyguardManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.sax.StartElementListener;
import android.support.v4.app.NotificationCompat;
import android.widget.Toast;

import com.example.wifiunlockscreen.Menu;
import com.example.wifiunlockscreen.R;

//Clase creada ya que pregunto en muchos sitios de la app el nombre de la wifi conectada
public final class WifiInfoManager {

	private KeyguardManager keyguardManager;
	private KeyguardLock lock;
	private WifiManager wifi;
	
	private WifiFriendDAO datasource;

	private final Handler mHandler = new Handler();
	
	public WifiInfoManager(Context ctx){
		initializeLockers(ctx);
		initializeBBDDObject(ctx);
	}
	

	//TODO borrar si en un desarrollo avanzado o terminado se sigue sin usar este metodo
	public String getNameWifiConnected(){
		String name ="";
		
		WifiInfo wifiConectado = wifi.getConnectionInfo();
		name = wifiConectado.getSSID();
		
		//TODO excepciones
		/*if(name!=null && !name.equals("<unknown ssid>")){
			texto.setText("Estas conectado a "+name);
		}else{
			texto.setText("No estas conectado a ninguna red Wifi");
		}*/
		
		return name;
	}
	
	public static String getCurrentSsid(Context context) {
		
		  String ssid = null;
		  
		  ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
		  NetworkInfo networkInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
		  if (networkInfo.isConnected()) {
		    final WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
		    final WifiInfo connectionInfo = wifiManager.getConnectionInfo();
		    if (connectionInfo != null && connectionInfo.getSSID()!="") {
		      ssid = connectionInfo.getSSID();
		    }
		  }
		  
		  return ssid;
	}	
	
	
	
	
	//Este metodo inicializa los objetos para habilitar o deshabilitar el bloqueo de pantalla
	private void initializeLockers(Context context){
		
        //Configuramos el bloqueo de pantalla para habilitarlo o deshabilitarlo dependiendo del caso
        keyguardManager = (KeyguardManager)context.getSystemService(Activity.KEYGUARD_SERVICE);
        lock = keyguardManager.newKeyguardLock(context.KEYGUARD_SERVICE);
        
	}
	
	//MEtodo que inicia el receptor con los filtros necesarios
	public void iniciaReceptor(Context contexto){
		
		final IntentFilter filters = new IntentFilter();
        filters.addAction("android.net.wifi.WIFI_STATE_CHANGED");
        filters.addAction("android.net.wifi.STATE_CHANGE");
        filters.addAction(Intent.ACTION_SCREEN_ON);
        filters.addAction(Intent.ACTION_SCREEN_OFF);
        filters.addAction(Intent.ACTION_USER_PRESENT);
        contexto.registerReceiver(receiver, filters);
		
	}
	
	//Metodo que usamos para dejar a valores iniciales ciertos objetos necesarios
	public void finalizeStats(){
		notificationID=1;
	}
	
	//Metodo que deshabilita el bloqueo de pantalla
	public void disableLock(Context context){		
		
    	if(lock !=null){
    		//habilitamos el bloqueo, por si acaso, antes de desactivarlo
    		lock.reenableKeyguard();
    		
    		//lock.disableKeyguard();
    		mHandler.postDelayed(runDisableKeyguard(context), 300);
    		

    	}else{
    		initializeLockers(context);
    		mHandler.postDelayed(runDisableKeyguard(context), 300);
    	}

		
		//Mostrar notificacion persistente(o no, dependiendo de la configuracion(futuro))
		//La notificacion puede tener una accion si se pulsa que vaya a la configuracion de la app
    	displayNotification(context);
		
		
	}
	
	//Metodo que habilita el bloqueo de pantalla
	public void enableLock(Context context){
		
		if(lock!=null){
			mHandler.removeCallbacks(runDisableKeyguard(context));
			lock.reenableKeyguard();
			lock = null;
		}

		
        NotificationManager nm = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
        
        // Cancelamos la Notificacion que hemos comenzado
        nm.cancel(notificationID);
        notificationID=1;
	}
	
	//ID de notificacion para cerrarla o viajar a otra actividad(de confoiguracion por ejemplo)
	int notificationID = 1;
	
    protected void displayNotification(Context context){
    	
    	if(notificationID!=2){//Numero 2 indica que ya estamos mostrando la notificacion
        	/*Lo primero que haremos es crear un objeto Intent el cual contiene la referencia a la actividad actual 
        	 * y a la que iremos mas tarde, en este caso, es la segunda Activity que vamos a crear. 
        	 * A este mismo Intent, le vamos a agregar el ID de la notificacion, ya que luego en la siguiente actividad, 
        	 * usaremos este ID para cancelarla y eliminarla de la barra de notificaciones.*/
        	//Intent i = new Intent(this, NotificationView.class);
            //i.putExtra("notificationID", notificationID);
             
            
            /*Ahora creamos otro Intent, en este caso pertenece a la clase PendingIntent. 
             * Estos Intent nos ayudan a realizar una acci�n en nuestra aplicaci�n, incluso mas tarde, 
             * sin importar si nuestra aplicaci�n se est� ejecutando o no, y la inicializamos con el context de la 
             * aplicaci�n, un request code para el intent, el intent para lanzar la aplicaci�n objetivo y flag que 
             * especifica en que actividad ser� lanzada.*/
            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, new Intent(context, Menu.class), 0);
        	
            /*El paso siguiente es obtener la instancia de la clase NotificationManager, 
             * la cual usaremos para lanzar luego nuestra Notificacion.*/
            NotificationManager nm = (NotificationManager)context.getSystemService(context.NOTIFICATION_SERVICE);
            	
            /*Ahora vamos a crear un objeto de la clase Notification, cuya construcci�n vamos a crear mediante el 
             * Builder de la clase NotificationCompat, el cual es el usado para dispositivos android cuya versi�n es inferior a API 11, 
             * es por ello que hemos importado con anterioridad la librer�a de soporte. 
             * En el caso de que nuestra aplicaci�n solo sea para dispositivos con una versi�n de Android superior a la API 11, 
             * podemos usar Notification.Builder para construir la Notification. 
             * Esta es la �nica diferencia.*/
            CharSequence ticker ="Nueva entrada en WifiUnlockScreen";
            CharSequence contentTitle = "WifiUnlockScreen";
            CharSequence contentText = "Debloqueo de pantalla deshabilitado";
            Notification noti = new NotificationCompat.Builder(context)
                                    .setContentIntent(pendingIntent)//Cuando pulse en la notificacion se ejecutara la Intent pendiente(el menu principal)
                                    .setTicker(ticker)
                                    .setContentTitle(contentTitle)
                                    .setContentText(contentText)
                                    .setSmallIcon(R.drawable.ic_launcher)
                                    //.addAction(R.drawable.ic_launcher, ticker, pendingIntent)
                                    //.setVibrate(new long[] {100, 250, 100, 500})
                                    .build();
            
            noti.flags = noti.FLAG_NO_CLEAR;//No poder borrarla
            
            /*Como �ltimo en esta actividad, a�adimos una notificaci�n al NotificationManager, 
             * pasando como argumentos el ID de la notificacion y el objeto Notification que hemos construido.*/
            
            //Establecemos otro valor a la variable notificationID para no volver a cargarla si ya esta mostrandose
            notificationID = 2;
            
            nm.notify(notificationID, noti);
    	}
    	

    }	

	
    private void initializeBBDDObject(Context contexto){
    	datasource = new  WifiFriendDAO(contexto);
    }
    
    public void iniciaBBDD(Context contexto){
		
		datasource.open();
    }
    
    public void cierraBBDD(){
    	datasource.close();
    }
    
    public void abreBBDD(){
    	datasource.open();
    }
        
    public Boolean esFavorito(String nombreWifi){
    	Boolean fav = false; 
    	datasource.open();
    	WifiFriendObject wifiFriend = datasource.getByName(nombreWifi);
    	
    	datasource.close();
    	
    	if(wifiFriend!=null){
    		fav=true;
    	}
    	
    	return fav;
    }
    

    public Boolean addFvorita(String name){
    	return datasource.saveFriend(name);
    }
    
    public List<WifiFriendObject> getWifiFriendList(){
    	List<WifiFriendObject> wifiFriendList;
    	
    	datasource.open();
    	
    	wifiFriendList = datasource.getAllFriends();
    	
    	datasource.close();
    	
    	return wifiFriendList;
    	
    }
    
    public Boolean deleteFriend(WifiFriendObject wifi){
    	Boolean borrado = Boolean.FALSE;
    	
    	if(wifi!=null){
    		
    		datasource.open();
    		
    		Integer result = (Integer) datasource.deleteFriend(wifi);
    		
    		datasource.close();
    		
    		if(result>0){
    			borrado = Boolean.TRUE;
    			
    			
    		}
    		
    	}
    	
    	return borrado;
    }
    
    public Boolean isLocked(){
    	
    	boolean locked = keyguardManager.inKeyguardRestrictedInputMode();
    	
    	return locked;
    }
    
    
    /*Metodos de prueba de nuevas tecnicas para deshabilitar el bloqueo de pantalla*/
    
    private BroadcastReceiver receiver;//seteado en el servicio antes de ejecutar el receptor
    
    public void setEnablednessOfKeyguard(boolean enabled, Context contexto) {
    	
    	final Context contexto2;//hace falta que sea final para el runable
    	contexto2 = contexto;
    	final Runnable runDisableKeyguard = new Runnable() {
    		public void run() {
    		lock = keyguardManager.newKeyguardLock(contexto2.KEYGUARD_SERVICE);
    		lock.disableKeyguard();
    		}
    	};
    	
    	
		if (!enabled) {
			if (lock != null) {
					//contexto.unregisterReceiver(receiver);
					mHandler.removeCallbacks(runDisableKeyguard);
					lock.reenableKeyguard();
					lock = null;
			}
		} else {
			if (keyguardManager.inKeyguardRestrictedInputMode()) {
				//iniciaReceptor(contexto);
					
			} else {
			if (lock != null){
				lock.reenableKeyguard();
			}else{
				//iniciaReceptor(contexto);
			}
				mHandler.postDelayed(runDisableKeyguard, 300);
			}
		}
	}


	public BroadcastReceiver getReceiver() {
		return receiver;
	}


	public void setReceiver(BroadcastReceiver receiver) {
		this.receiver = receiver;
	}
    
    private Runnable runDisableKeyguard(Context context){
    	final Context contexto2;//hace falta que sea final para el runable
    	contexto2 = context;
    	final Runnable runDisableKeyguard = new Runnable() {
    		public void run() {
    		//lock = keyguardManager.newKeyguardLock(contexto2.KEYGUARD_SERVICE);
    		if(lock!=null){
    			lock.disableKeyguard();
    		}
    		
    		}
    	};
    	
    	return runDisableKeyguard;
    }
    
}
